

package com.mercury.alibaba.handler;

import com.mercury.alibaba.model.NoticeData;
import com.mercury.alibaba.model.SmsSendFailEvent;
import com.mercury.alibaba.model.SmsSendFinallyEvent;
import com.mercury.alibaba.model.SmsSendSuccessEvent;
import com.mercury.alibaba.properties.AbstractHandlerProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.lang.Nullable;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 抽象发送处理.
 *
 * @param <P> 配置类类型
 * @author mercury
 */
public abstract class AbstractSendHandler<P extends AbstractHandlerProperties<?>> implements SendHandler {

    /**
     * 配置.
     */
    protected final P properties;

    private final ApplicationEventPublisher eventPublisher;

    public AbstractSendHandler(P properties, @Nullable ApplicationEventPublisher eventPublisher) {
        this.properties = properties;
        this.eventPublisher = eventPublisher;
    }

    @Override
    public boolean acceptSend(@Nullable String type) {
        return properties.getTemplates().containsKey(type);
    }

    /**
     * 获取通道名称.
     *
     * @return 通道名称
     */
    public abstract String getChannelName();

    /**
     * 发布发送成功事件.
     *
     * @param noticeData 通知内容
     * @param phones     手机号列表
     */
    protected final void publishSendSuccessEvent(NoticeData noticeData, Collection<String> phones) {
        if (eventPublisher == null) {
            return;
        }
        eventPublisher.publishEvent(
                new SmsSendSuccessEvent(this, getChannelName(), phones, noticeData.getMsgId(), noticeData.getType(), noticeData.getParams()));
        publishSendFinallyEvent(noticeData, phones);
    }

    /**
     * 发布发送失败事件.
     *
     * @param noticeData 通知内容
     * @param phones     手机号列表
     * @param cause      源异常
     */
    protected final void publishSendFailEvent(NoticeData noticeData, Collection<String> phones, Throwable cause) {
        if (eventPublisher == null) {
            return;
        }
        eventPublisher.publishEvent(
                new SmsSendFailEvent(this, getChannelName(), phones, noticeData.getMsgId(), noticeData.getType(), noticeData.getParams(),
                        cause));
        publishSendFinallyEvent(noticeData, phones);
    }

    /**
     * 发布发送结束事件.
     *
     * @param noticeData 通知内容
     * @param phones     手机号列表
     */
    private void publishSendFinallyEvent(NoticeData noticeData, Collection<String> phones) {
        if (eventPublisher == null) {
            return;
        }
        eventPublisher.publishEvent(
                new SmsSendFinallyEvent(this, getChannelName(), phones, noticeData.getMsgId(), noticeData.getType(), noticeData.getParams()));
    }

    /**
     * 动态拼接发送模板字符串
     * @param content
     * @param map
     * @return
     */
    private String renderString(String content, Map<String, Object> map) {
        Set<Map.Entry<String, Object>> sets = map.entrySet();
        for (Map.Entry<String, Object> entry : sets) {
            String regex = "\\$\\{" + entry.getKey() + "}";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(content);
            content = matcher.replaceAll(String.valueOf(entry.getValue()));
        }
        return content;
    }
}
